package com.java.app.hacktouch

import android.app.Activity
import android.app.AlertDialog
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.*
import android.content.pm.ActivityInfo
import android.gesture.GestureLibraries
import android.gesture.GestureLibrary
import android.gesture.GestureOverlayView
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.Message
import android.support.design.widget.FloatingActionButton
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.util.Log
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.java.app.hacktouch.bluetooth.BtDevice
import com.java.app.hacktouch.bluetooth.BtIf
import com.java.app.hacktouch.gesture.CreateGestureActivity
import com.java.app.hacktouch.gesture.GestureParams
import com.java.app.hacktouch.gesture.OperationGesture
import com.java.app.hacktouch.gesture.RemoveGestureActivity
import com.java.app.hacktouch.mouse.MouseDialog
import com.java.app.hacktouch.parameter.MotionMode
import com.java.app.hacktouch.parameter.ParamsDB
import com.java.app.hacktouch.view.HackView
import java.io.File
import java.util.*

class MainActivity : AppCompatActivity() {

    private var mBluetoothAdapter: BluetoothAdapter? = null
    private var mBtDevice: BluetoothDevice? = null

    private var hackView: HackView? = null
    private var gestures: GestureOverlayView? = null
    private var sp: SharedPreferences? = null
    private var mParamsDB: ParamsDB? = null

    private val mHandler = object : Handler() {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                MESSAGE_STATE_CHANGE -> when (msg.arg1) {
                    BtDevice.BtState.STATE_CONNECTED -> {
                        Log.d(TAG, "STATE_CONNECTED")
                        Toast.makeText(applicationContext, "蓝牙设备连接成功",
                                Toast.LENGTH_LONG).show()
                        hackView!!.startReport()
                    }
                    BtDevice.BtState.STATE_CONNECTING -> {
                    }
                    BtDevice.BtState.STATE_LISTEN, BtDevice.BtState.STATE_NONE -> {
                    }
                }

                MESSAGE_TOAST -> Toast.makeText(applicationContext, msg.data.getString(TOAST),
                        Toast.LENGTH_LONG).show()

                MESSAGE_READ -> {
                }

                MESSAGE_UNBONDED -> Toast.makeText(applicationContext, msg.data.getString(TOAST),
                        Toast.LENGTH_LONG).show()

                CONNECT_FAIL -> {
                }

                CONNECT_RESET -> {
                    BtIf.mCommandService!!.stop()
                    BtIf.mCommandService = null
                    BtIf.mCommandService = BtDevice(this@MainActivity, this)
                    BtIf.mCommandService!!.connect(mBtDevice!!)
                }
            }//                    Intent enableIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
            //                    startActivityForResult(enableIntent, REQUEST_BT_BOND);

        }
    }

    private val mReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            if (BluetoothDevice.ACTION_FOUND == action) {
                val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                if (device.name == null || device.name.length < mParamsDB!!.GetBTParams().length) {
                    val msg = mHandler.obtainMessage(MainActivity.MESSAGE_TOAST)
                    val bundle = Bundle()
                    bundle.putString(MainActivity.TOAST, "获取蓝牙设备设备名失败")
                    msg.data = bundle
                    mHandler.sendMessage(msg)
                    return
                }

                if (device.name.substring(0, mParamsDB!!.GetBTParams().length).equals(mParamsDB!!.GetBTParams(), ignoreCase = true)) {
                    when (device.bondState) {
                        BluetoothDevice.BOND_BONDED -> {
                            mBtDevice = device
                            BtIf.mCommandService!!.connect(device)
                            val msg = mHandler.obtainMessage(MainActivity.MESSAGE_TOAST)
                            val bundle = Bundle()
                            bundle.putString(MainActivity.TOAST, "正在连接蓝牙设备:" + device.name)
                            msg.data = bundle
                            mHandler.sendMessage(msg)
                        }
                        else -> {
                            val msg_1 = mHandler.obtainMessage(MainActivity.MESSAGE_UNBONDED)
                            val bundle_1 = Bundle()
                            bundle_1.putString(MainActivity.TOAST, "蓝牙设备:" + device.name + " 未配对，请重新配对 ")
                            msg_1.data = bundle_1
                            mHandler.sendMessage(msg_1)
                        }
                    }
                }
            }
        }
    }

    /*
    * 两次返回键才真正退出应用
    * */
    private var isQuit: Boolean? = false
    internal var quitTimer = Timer()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        requestedOrientation = ActivityInfo
                .SCREEN_ORIENTATION_LANDSCAPE //横屏
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN) //全屏

        setContentView(R.layout.activity_main)

        hackView = findViewById(R.id.paint_layout)
        gestures = findViewById(R.id.gestures_layout)

        InitGesture()
        InitButton()
        LoadParams()
        InitBluetoothDevice()
    }

    private fun LoadParams() {
        sp = this.getSharedPreferences("SP", Context.MODE_PRIVATE)
        mParamsDB = ParamsDB(sp!!)
        hackView!!.setMouseParams(mParamsDB!!.GetMouseParams()!!)
        if (store != null) {
            store.load()

            for (name in store.gestureEntries) {
                Log.i(TAG, "gesture name: " + name)
            }
        }
    }

    private fun InitButton() {
        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)

        val fab = findViewById<FloatingActionButton>(R.id.fab)
        fab.setOnClickListener { view ->
            val setmode: MotionMode
            val info: String
            if (hackView!!.mode === MotionMode.MOUSE_MODE) {
                setmode = MotionMode.GESTURE_MODE
                info = "切换为手势识别模式"
                setGestures(true)
            } else {
                setmode = MotionMode.MOUSE_MODE
                info = "切换为鼠标模式"
                setGestures(false)
            }
            hackView!!.mode = setmode

            Snackbar.make(view, info, Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show()
        }
    }

    private fun setGestures(enabled: Boolean) {
        if (enabled == false) {
            gestures!!.isEventsInterceptionEnabled = false
            gestures!!.isEnabled = false
        } else {
            gestures!!.isEventsInterceptionEnabled = true
            gestures!!.isEnabled = true
        }
    }

    private fun InitGesture() {

        gestures!!.gestureStrokeType = GestureParams.strokeType
        gestures!!.gestureStrokeWidth = GestureParams.strokeWidth.toFloat()
        gestures!!.fadeOffset = GestureParams.fadeOffset
        gestures!!.gestureColor = GestureParams.color

        setGestures(false)

        gestures!!.addOnGesturePerformedListener { gestureOverlayView, gesture ->
            if (store != null) {
                store.load()
                val predictions = store.recognize(gesture)

                Log.i("performed", "performed size:" + predictions.size)
                var gesture_id = -1
                var gesture_score = 0.0
                for (i in predictions.indices) {
                    Log.i("performed", "name: " + predictions[i].name + " score: " + predictions[i].score)
                    if (predictions[i].score > GestureParams.score) {
                        if (predictions[i].score > gesture_score) {
                            gesture_score = predictions[i].score
                            gesture_id = i
                        }
                    }
                }

                if (gesture_id != -1) {
                    Toast.makeText(this@MainActivity, predictions[gesture_id].name, Toast.LENGTH_SHORT).show()
                    OperationGesture.excuteGesture(predictions[gesture_id].name)
                }
            }
        }
    }

    /*
    * 初始化蓝牙连接,支持重新连接
    * */
    private fun InitBluetoothDevice() {
        // TODO Auto-generated method stub

        if (mBluetoothAdapter == null) {
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
            if (mBluetoothAdapter == null) {
                Toast.makeText(this, "蓝牙设备无效", Toast.LENGTH_LONG).show()
                finish()
                return
            }
        }

        if (!mBluetoothAdapter!!.isEnabled) {
            val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableIntent, REQUEST_ENABLE_BT)
        } else {
            if (BtIf.mCommandService == null) {
                BtIf.mCommandService = BtDevice(this, mHandler)
            }
            BtDeviceDiscovery()
        }
    }

    private fun disconnectDevice() {
        if (mBluetoothAdapter!!.isDiscovering)
            mBluetoothAdapter!!.cancelDiscovery()

        this.unregisterReceiver(mReceiver)

        if (BtIf.mCommandService != null) {
            BtIf.mCommandService!!.stop()
            while (BtIf.mCommandService!!.state != BtDevice.BtState.STATE_NONE) {
                //wait for bt thread exit
                try {
                    Thread.sleep(1000)
                } catch (e: InterruptedException) {
                    Log.e(TAG, "disconnect device exception", e)
                }

            }
            BtIf.mCommandService = null
        }
    }

    private fun BtDeviceDiscovery() {
        val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
        registerReceiver(mReceiver, filter)

        if (mBluetoothAdapter!!.isDiscovering)
            mBluetoothAdapter!!.cancelDiscovery()

        mBluetoothAdapter!!.startDiscovery()
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        val id = item.itemId


        if (id == R.id.mouse_settings) {
            val mouseDialog = AlertDialog.Builder(this@MainActivity).create()
            mouseDialog.show()
            mouseDialog.window!!.setContentView(R.layout.mouse_setting)
            MouseDialog.promptDialog(applicationContext,
                    mouseDialog,
                    mParamsDB!!,
                    hackView!!)
            return true
        } else if (id == R.id.gesture_settings) {
            val gestureDialog = AlertDialog.Builder(this@MainActivity).create()
            gestureDialog.show()
            gestureDialog.window!!.setContentView(R.layout.gesture_setting)
            val bt_gesture_add = gestureDialog.window!!.findViewById<Button>(R.id.bt_gesture_add)
            val bt_gesture_remove = gestureDialog.window!!.findViewById<Button>(R.id.bt_gesture_remove)

            bt_gesture_add.setOnClickListener {
                val intent = Intent(this@MainActivity, CreateGestureActivity::class.java)
                startActivityForResult(intent, REQUEST_NEW_GESTURE)
            }
            bt_gesture_remove.setOnClickListener {
                val intent = Intent(this@MainActivity, RemoveGestureActivity::class.java)
                startActivityForResult(intent, REQUEST_NEW_GESTURE)
            }
        } else if (id == R.id.bt_settings) {
            val builder = AlertDialog.Builder(this@MainActivity)
            val bt_ed = EditText(this@MainActivity)
            bt_ed.setText(mParamsDB!!.GetBTParams())
            builder.setTitle("请输入蓝牙名称")
            builder.setIcon(android.R.drawable.ic_dialog_info)
            builder.setView(bt_ed)
            builder.setPositiveButton("确定") { dialogInterface, i ->
                mParamsDB!!.SetBTParams(bt_ed.text.toString())

                val alertDialogBuilder = AlertDialog.Builder(this@MainActivity)
                alertDialogBuilder.setPositiveButton("确定", null)
                val alertDialog = alertDialogBuilder.create()
                alertDialog.setMessage("需要重现启动APP才能使蓝牙设置生效")
                alertDialog.show()
            }
            builder.setNegativeButton("取消", null)
            val dialog = builder.create()
            dialog.show()
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)

        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                REQUEST_NEW_GESTURE -> {
                    store!!.load()
                    Log.i(TAG, "gesture size: " + store.gestureEntries.size)
                    for (aa in store.gestureEntries) {
                        Log.i(TAG, "gesture name: " + aa)
                    }
                }
            }
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {

            if (isQuit == false) {

                isQuit = true
                Toast.makeText(baseContext, "再按一次返回键退出程序", Toast.LENGTH_SHORT).show()

                val task = object : TimerTask() {
                    override fun run() {
                        isQuit = false
                    }
                }
                quitTimer.schedule(task, 2000)
            } else {
                hackView!!.stopReport()
                disconnectDevice()
                finish()
                System.exit(0)
            }

        }
        return false
    }

    companion object {

        private val TAG = "MainActivity"

        private val REQUEST_ENABLE_BT = 0

        val MESSAGE_STATE_CHANGE = 0
        val MESSAGE_TOAST = 1
        val MESSAGE_READ = 2
        val MESSAGE_UNBONDED = 3
        val CONNECT_FAIL = 4
        val CONNECT_RESET = 5

        val TOAST = "Bt_Toast"

        private val REQUEST_NEW_GESTURE = 1

        private val mStoreFile = File(Environment.getExternalStorageDirectory(), "gestures")
        val store: GestureLibrary? = GestureLibraries.fromFile(mStoreFile)
    }
}
